﻿using Furion;
using Furion.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using MyProject.Entity;
using MyProject.IService.SystemManage;
using MyProject.Util;
using MyProject.Util.Helper;
using NewLife.MQTT;
using SqlSugar;
using System;
using System.Threading.Tasks;

namespace MyProject.Mqtt
{
    public class MqttClientCenter : ISingleton
    {
        private static MqttClient _mqttClient;
        private static MqttClient mqttClient
        {
            get
            {
                if (_mqttClient == null)
                {
                    _mqttClient = new MqttClient
                    {
                        Server = $"tcp://{GlobalContext.SystemConfig.MqttTcpServer}:{GlobalContext.SystemConfig.MqttTcpHost}",
                        UserName = GlobalContext.SystemConfig.MqttUserName,
                        Password = GlobalContext.SystemConfig.MqttPasswrod,
                        ClientId = Guid.NewGuid() + ""
                    };
                }
                return _mqttClient;
            }
        }

        #region 公开方法

        /// <summary>
        /// 打开连接并订阅配置主题
        /// </summary>
        public static async Task OpenConnectAsync()
        {
            // 配置关闭了的话，就不再执行了
            if (GlobalContext.SystemConfig.MqttIsOpen == false)
                return;

            // 查询所需订阅的主题
            var mqttThemeBll = App.ServiceProvider.GetService<IMqttThemeService>();
            var themes = await mqttThemeBll.GetList(new Model.Param.SystemManage.MqttThemeListParam() { IsSubscribe = true });

            try
            {
                // 创建连接
                await mqttClient.ConnectAsync();

                // 批量订阅配置的主题
                foreach (var topic in themes)
                  await  Subscribe(topic.ThemeName);
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex);
            }
        }

        /// <summary>
        /// 订阅主题
        /// </summary>
        public static async Task Subscribe(string topic) {

            await _mqttClient.SubscribeAsync(topic, async (e) =>
            {
                // 记录日志（采用sqlsugar）
                await LogMqttMsg(e.Topic, e.Payload.ToStr());

                // 执行业务，若无定义相关业务代码，则会在日志文件记下来哦
                var jobCenter = App.ServiceProvider.GetService<MqttJobCenter>();
                await jobCenter.DoWork(e.Topic, e.Payload.ToStr());
            });
        }

        /// <summary>
        /// 取消订阅
        /// </summary>
        public static async Task Unsubscribe(params string[] topic)
        {
           await _mqttClient.UnsubscribeAsync(topic);
        }

        #endregion

        #region 私有方法

        private static async Task LogMqttMsg(string Topic, string Payload)
        {
            var sqlsugar = App.ServiceProvider.GetService<ISqlSugarRepository<MqttMsgEntity>>();
            var entity = new MqttMsgEntity()
            {
                Id = IdGeneratorHelper.Instance.GetId(),
                Msg = Payload,
                ThemeName = Topic,
                Time = DateTime.Now
            };
            await sqlsugar.InsertAsync(entity);
        }

        #endregion
    }
}